use crate::SystemCommands;
use indicatif::{ProgressBar, ProgressStyle};
use sysinfo::{System, SystemExt, ProcessExt, Pid};
use std::time::Duration;
use std::thread;

pub fn handle_system_commands(command: SystemCommands, verbose: bool) -> Result<(), Box<dyn std::error::Error>> {
    match command {
        SystemCommands::Info { detailed } => {
            system_info(detailed, verbose)?;
        },
        SystemCommands::Monitor { interval, items } => {
            system_monitor(interval, &items, verbose)?;
        },
        SystemCommands::Process { operation, pid } => {
            process_management(&operation, pid, verbose)?;
        },
    }
    Ok(())
}

fn system_info(detailed: bool, verbose: bool) -> Result<(), Box<dyn std::error::Error>> {
    let mut sys = System::new_all();
    sys.refresh_all();
    
    println!("🖥️  系统信息:");
    println!("  操作系统: {}", std::env::consts::OS);
    println!("  架构: {}", std::env::consts::ARCH);
    println!("  Rust版本: {}", env!("CARGO_PKG_VERSION"));
    
    if detailed {
        println!("  主机名: {}", sys.host_name().unwrap_or_else(|| "Unknown".to_string()));
        println!("  内核版本: {}", sys.kernel_version().unwrap_or_else(|| "Unknown".to_string()));
        println!("  系统版本: {}", sys.os_version().unwrap_or_else(|| "Unknown".to_string()));
    }
    
    // 内存信息
    let total_memory = sys.total_memory();
    let used_memory = sys.used_memory();
    let free_memory = sys.free_memory();
    
    println!("  内存:");
    println!("    总计: {}", format_bytes(total_memory));
    println!("    已用: {} ({:.1}%)", format_bytes(used_memory), 
        (used_memory as f64 / total_memory as f64) * 100.0);
    println!("    可用: {} ({:.1}%)", format_bytes(free_memory),
        (free_memory as f64 / total_memory as f64) * 100.0);
    
    // CPU信息
    let cpu_count = sys.cpus().len();
    let cpu_usage = sys.global_cpu_info().cpu_usage();
    
    println!("  CPU:");
    println!("    核心数: {}", cpu_count);
    println!("    使用率: {:.1}%", cpu_usage);
    
    if detailed {
        for (i, cpu) in sys.cpus().iter().enumerate() {
            println!("    CPU {}: {:.1}%", i, cpu.cpu_usage());
        }
    }
    
    // 磁盘信息
    let disks = sys.disks();
    println!("  磁盘:");
    for disk in disks {
        let total_space = disk.total_space();
        let available_space = disk.available_space();
        let used_space = total_space - available_space;
        
        println!("    {}: {} / {} ({:.1}% 已用)",
            disk.name().to_string_lossy(),
            format_bytes(used_space),
            format_bytes(total_space),
            (used_space as f64 / total_space as f64) * 100.0
        );
    }
    
    if verbose {
        println!("  进程数: {}", sys.processes().len());
        println!("  启动时间: {:?}", sys.boot_time());
    }
    
    Ok(())
}

fn system_monitor(interval: u64, items: &[String], verbose: bool) -> Result<(), Box<dyn std::error::Error>> {
    println!("📊 系统监控 (按Ctrl+C停止)");
    println!("================================");
    
    let mut sys = System::new_all();
    let mut count = 0;
    
    loop {
        sys.refresh_all();
        
        let mut output = Vec::new();
        
        if items.is_empty() || items.contains(&"cpu".to_string()) {
            let cpu_usage = sys.global_cpu_info().cpu_usage();
            output.push(format!("CPU: {:.1}%", cpu_usage));
        }
        
        if items.is_empty() || items.contains(&"memory".to_string()) {
            let total_memory = sys.total_memory();
            let used_memory = sys.used_memory();
            let memory_percent = (used_memory as f64 / total_memory as f64) * 100.0;
            output.push(format!("内存: {:.1}%", memory_percent));
        }
        
        if items.is_empty() || items.contains(&"disk".to_string()) {
            let disks = sys.disks();
            let mut disk_usage = Vec::new();
            for disk in disks {
                let total_space = disk.total_space();
                let available_space = disk.available_space();
                let used_space = total_space - available_space;
                let usage_percent = (used_space as f64 / total_space as f64) * 100.0;
                disk_usage.push(format!("{:.1}%", usage_percent));
            }
            output.push(format!("磁盘: {}", disk_usage.join(", ")));
        }
        
        if items.is_empty() || items.contains(&"network".to_string()) {
            let networks = sys.networks();
            let mut network_info = Vec::new();
            for (interface_name, network) in networks {
                let received = network.received();
                let transmitted = network.transmitted();
                network_info.push(format!("{}: ↓{} ↑{}", 
                    interface_name, 
                    format_bytes(received), 
                    format_bytes(transmitted)
                ));
            }
            if !network_info.is_empty() {
                output.push(format!("网络: {}", network_info.join(", ")));
            }
        }
        
        let timestamp = chrono::Utc::now().format("%H:%M:%S");
        println!("[{}] {}", timestamp, output.join(" | "));
        
        if verbose && count % 10 == 0 {
            println!("  进程数: {}, 线程数: {}", 
                sys.processes().len(),
                sys.processes().values().map(|p| p.num_threads()).sum::<usize>()
            );
        }
        
        thread::sleep(Duration::from_secs(interval));
        count += 1;
    }
}

fn process_management(operation: &str, pid: Option<u32>, verbose: bool) -> Result<(), Box<dyn std::error::Error>> {
    let mut sys = System::new_all();
    sys.refresh_all();
    
    match operation {
        "list" => {
            list_processes(&sys, verbose)?;
        },
        "kill" => {
            if let Some(pid) = pid {
                kill_process(pid, verbose)?;
            } else {
                return Err("终止进程需要指定进程ID".into());
            }
        },
        "info" => {
            if let Some(pid) = pid {
                process_info(&sys, pid, verbose)?;
            } else {
                return Err("查看进程信息需要指定进程ID".into());
            }
        },
        _ => return Err("不支持的操作".into()),
    }
    
    Ok(())
}

fn list_processes(sys: &System, verbose: bool) -> Result<(), Box<dyn std::error::Error>> {
    let mut processes: Vec<_> = sys.processes().iter().collect();
    processes.sort_by(|a, b| b.1.cpu_usage().partial_cmp(&a.1.cpu_usage()).unwrap());
    
    println!("📋 进程列表:");
    println!("{:<8} {:<20} {:<8} {:<8} {:<12} {}", 
        "PID", "名称", "CPU%", "内存%", "内存使用", "状态");
    println!("{}", "-".repeat(80));
    
    for (pid, process) in processes.iter().take(20) {
        let memory_usage = process.memory();
        let memory_percent = if sys.total_memory() > 0 {
            (memory_usage as f64 / sys.total_memory() as f64) * 100.0
        } else {
            0.0
        };
        
        println!("{:<8} {:<20} {:<8.1} {:<8.1} {:<12} {}", 
            pid.as_u32(),
            truncate_string(&process.name(), 20),
            process.cpu_usage(),
            memory_percent,
            format_bytes(memory_usage),
            if process.status() == sysinfo::ProcessStatus::Run { "运行" } else { "其他" }
        );
    }
    
    if verbose {
        println!("\n总进程数: {}", processes.len());
    }
    
    Ok(())
}

fn kill_process(pid: u32, verbose: bool) -> Result<(), Box<dyn std::error::Error>> {
    use std::process::Command;
    
    println!("⚠️  正在终止进程 {}...", pid);
    
    let output = if cfg!(target_os = "windows") {
        Command::new("taskkill")
            .args(&["/PID", &pid.to_string(), "/F"])
            .output()?
    } else {
        Command::new("kill")
            .args(&["-9", &pid.to_string()])
            .output()?
    };
    
    if output.status.success() {
        println!("✅ 进程 {} 已终止", pid);
    } else {
        let error = String::from_utf8_lossy(&output.stderr);
        println!("❌ 终止进程失败: {}", error);
    }
    
    if verbose {
        println!("命令输出: {}", String::from_utf8_lossy(&output.stdout));
    }
    
    Ok(())
}

fn process_info(sys: &System, pid: u32, verbose: bool) -> Result<(), Box<dyn std::error::Error>> {
    let pid = Pid::from_u32(pid);
    
    if let Some(process) = sys.process(pid) {
        println!("📋 进程信息:");
        println!("  PID: {}", pid.as_u32());
        println!("  名称: {}", process.name());
        println!("  状态: {:?}", process.status());
        println!("  CPU使用率: {:.1}%", process.cpu_usage());
        println!("  内存使用: {} ({:.1}%)", 
            format_bytes(process.memory()),
            (process.memory() as f64 / sys.total_memory() as f64) * 100.0
        );
        println!("  线程数: {}", process.num_threads());
        
        if let Some(parent) = process.parent() {
            println!("  父进程: {}", parent.as_u32());
        }
        
        if verbose {
            println!("  启动时间: {:?}", process.start_time());
            println!("  运行时间: {:?}", process.run_time());
            if let Some(cmd) = process.cmd() {
                println!("  命令行: {}", cmd.join(" "));
            }
        }
    } else {
        println!("❌ 进程 {} 不存在", pid.as_u32());
    }
    
    Ok(())
}

// 辅助函数
fn format_bytes(bytes: u64) -> String {
    const UNITS: &[&str] = &["B", "KB", "MB", "GB", "TB"];
    let mut size = bytes as f64;
    let mut unit_index = 0;
    
    while size >= 1024.0 && unit_index < UNITS.len() - 1 {
        size /= 1024.0;
        unit_index += 1;
    }
    
    format!("{:.1} {}", size, UNITS[unit_index])
}

fn truncate_string(s: &str, max_len: usize) -> String {
    if s.len() <= max_len {
        s.to_string()
    } else {
        format!("{}...", &s[..max_len.saturating_sub(3)])
    }
}

pub fn get_system_uptime() -> Result<Duration, Box<dyn std::error::Error>> {
    let sys = System::new_all();
    Ok(Duration::from_secs(sys.uptime()))
}

pub fn get_load_average() -> Result<(f64, f64, f64), Box<dyn std::error::Error>> {
    // 在大多数系统上，负载平均值需要特殊处理
    // 这里提供一个简化的实现
    let sys = System::new_all();
    let cpu_count = sys.cpus().len() as f64;
    let cpu_usage = sys.global_cpu_info().cpu_usage() / 100.0;
    
    // 模拟负载平均值
    let load_1min = cpu_usage * cpu_count;
    let load_5min = load_1min * 0.8;
    let load_15min = load_1min * 0.6;
    
    Ok((load_1min, load_5min, load_15min))
}

